#ifndef SQ_QUEUE_HPP
#define SQ_QUEUE_HPP

#include "MasterQueue.hpp"
#include <iostream>
#include <cstdlib>


typedef int QElemType;

typedef struct {
    QElemType* base;
    int front;
    int rear;
} Queue;

class SqQueueC: public MasterQueue<Queue, QElemType> {
public:

    Status initQueue(Queue& q) override
    {
        q.base = new QElemType[QueueMaxSize];
        if (!q.base)
            exit(0);
        q.front = q.rear = 0;
        return Status::Ok;
    }

    Status destoryQueue(Queue& q) override
    {
        if (!q.base)
            return Status::Err;
        delete[] q.base;
        q.base = nullptr;
        q.front = q.rear = 0;
        return Status::Ok;
    }

    Status clearQueue(Queue& q) override
    {
        q.front = q.rear = 0;
        return Status::Ok;
    }

    inline bool queueEmpty(const Queue& q) override
    {
        return q.front == q.rear ? true : false;
    }

    int queueLength(const Queue& q) override
    {
        return (q.rear - q.front + QueueMaxSize) % QueueMaxSize;
    }

    QElemType getHead(Queue& q) override
    {
        if (q.front != q.rear)
            return q.base[q.front];
        return {};
    }

    Status enQueue(Queue& q, QElemType e) override
    {
        if ((q.rear + 1) % QueueMaxSize == q.front)
            return Status::Err;
        q.base[q.rear] = e;
        q.rear = (q.rear + 1) % QueueMaxSize;
        return Status::Ok;
    }

    Status deQueue(Queue& q, QElemType& e) override
    {
        if (q.front == q.rear)
            return Status::Err;
        e = q.base[q.front];
        q.front = (q.front + 1) % QueueMaxSize;
        return Status::Ok;
    }

    Status queueTraverse(const Queue q) override
    {
        if (q.base == nullptr) {
            return Status::Err;
        }

        for (int i = q.front; i != q.rear; i = (i+1)%QueueMaxSize){
            std::cout << q.base[i] << std::endl;      
        }
        return Status::Ok;
    }
};

#endif
